package com.hmall.trade.mq.listeners;

import cn.hutool.core.util.ObjectUtil;
import com.hmall.api.clients.PayClient;
import com.hmall.api.dto.PayOrderDTO;
import com.hmall.common.domain.DelayMessage;
import com.hmall.common.mq.handler.DelayMessagePostProcessor;
import com.hmall.trade.constants.MqConstants;
import com.hmall.trade.domian.po.Order;
import com.hmall.trade.service.IOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class OrderDelayCheckMessageListener {
    private final IOrderService orderService;
    private final RabbitTemplate rabbitTemplate;
    private final PayClient payClient;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConstants.ORDER_DELAY_CHECK_QUEUE, durable = "true"),
            exchange = @Exchange(name = MqConstants.ORDER_DELAY_CHECK_EXCHANGE, delayed = "true", type = ExchangeTypes.TOPIC),
            key = MqConstants.ORDER_DELAY_CHECK_KEY
    ))
    public void orderDelayMessageListener(DelayMessage<Long> msg) {
        Long orderId = msg.getCoreMsgData();
        log.warn("接受支付状态检测的延时消息，订单ID：{}", orderId);
        Order order = orderService.getById(orderId);
        //判断订单状态是否为已支付，已支付则不作进一步操作
        if (ObjectUtil.isEmpty(order) || order.getStatus() != 1) {
            log.info("订单已支付，无需再次检测:{}", orderId);
            return;
        }
        //判断支付单状态是否为已支付，已支付则不作进一步操作
        if (isPay(orderId)) {
            log.info("支付单已支付，无需再次检测:{}", orderId);
            return;
        }
        //判断订单是否超时，未超时则按既定计划重新发送延迟消息
        if (msg.havaNextDalyaTime()) {
            try {
                rabbitTemplate.convertAndSend(
                        MqConstants.ORDER_DELAY_CHECK_EXCHANGE,
                        MqConstants.ORDER_DELAY_CHECK_KEY,
                        msg,
                        new DelayMessagePostProcessor(msg.nextDalayTime())
                );
            } catch (AmqpException e) {
                log.error("发送延迟消息失败:{}", e);
            }
            return;
        }
        //订单超时，取消订单
        log.info("订单超时，取消订单:{}", orderId);
        orderService.cancelOrder(orderId);

    }

    private boolean isPay(Long orderId) {
        PayOrderDTO payOrderDTO = payClient.queryPayOrderByBizOrderNo(orderId);
        if (ObjectUtil.isNotEmpty(payOrderDTO) && payOrderDTO.getStatus() == 3) {
            return true;
        }
        return false;
    }
}
